package jmine.tec.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * Empty invocation handler that returns null for every method or returns a
 * default primitive value. To be used for testing pourposes.
 * 
 * @author takeshi
 * 
 */
public class EmptyInvocationHandler implements InvocationHandler {

    private static final Map<Class< ? >, Object> PRIMITIVE_VALUES =
            new HashMap<Class< ? >, Object>();

    static {
        // PRIMITIVE_VALUES.put(Boolean.class, Boolean.FALSE);
        PRIMITIVE_VALUES.put(boolean.class, Boolean.FALSE);
        // PRIMITIVE_VALUES.put(Short.class, Short.valueOf((short) 0));
        PRIMITIVE_VALUES.put(short.class, Short.valueOf((short) 0));
        // PRIMITIVE_VALUES.put(Byte.class, Byte.valueOf((byte) 0));
        PRIMITIVE_VALUES.put(byte.class, Byte.valueOf((byte) 0));
        // PRIMITIVE_VALUES.put(Character.class, Character.valueOf((char) 0));
        PRIMITIVE_VALUES.put(char.class, Character.valueOf((char) 0));
        // PRIMITIVE_VALUES.put(Float.class, 0f);
        PRIMITIVE_VALUES.put(float.class, 0f);
        // PRIMITIVE_VALUES.put(Double.class, 0.0d);
        PRIMITIVE_VALUES.put(double.class, 0.0d);
        PRIMITIVE_VALUES.put(int.class, 0);
        // PRIMITIVE_VALUES.put(Integer.class, 0);
        PRIMITIVE_VALUES.put(long.class, 0L);
        // PRIMITIVE_VALUES.put(Long.class, 0L);
    }

    /**
     * Processes a method invocation on a proxy instance and returns the result.
     * This method will be invoked on an invocation handler when a method is
     * invoked on a proxy instance that it is associated with.
     * 
     * @param proxy
     *            the proxy instance that the method was invoked on
     * 
     * @param method
     *            the <code>Method</code> instance corresponding to the
     *            interface method invoked on the proxy instance. The declaring
     *            class of the <code>Method</code> object will be the
     *            interface that the method was declared in, which may be a
     *            superinterface of the proxy interface that the proxy class
     *            inherits the method through.
     * 
     * @param args
     *            an array of objects containing the values of the arguments
     *            passed in the method invocation on the proxy instance, or
     *            <code>null</code> if interface method takes no arguments.
     *            Arguments of primitive types are wrapped in instances of the
     *            appropriate primitive wrapper class, such as
     *            <code>java.lang.Integer</code> or
     *            <code>java.lang.Boolean</code>.
     * 
     * @return <code>null</code>
     * 
     */
    public Object invoke(final Object proxy, final Method method, final Object[] args) {
        if (method.getReturnType().isPrimitive()) {
            return PRIMITIVE_VALUES.get(method.getReturnType());
        }
        return null;
    }
}
